package com.bsb.biz.shiro;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.bsb.base.common.config.Const;
import com.bsb.base.model.SysUser;
import com.bsb.biz.service.SysResourceService;
import com.bsb.biz.service.SysUserService;

public class CustomRealm extends AuthorizingRealm {
	@Autowired
	private SysUserService sysUserService;
	@Resource
	private SysResourceService sysResourceService;

	// 设置Realm名称
	@Override
	public void setName(String name) {
		super.setName("CustomRealm");
	}

	// 支持UsernamePasswordToken
	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof UsernamePasswordToken;
	}

	// 用于认证
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// 从token中获取用户身份信息
		String username = (String) token.getPrincipal();
		// 拿着username从数据库中进行查询
		// 如果查询不到返回null
		SysUser user = sysUserService.getUserByUsername(username);
		if (null == user) {
			throw new UnknownAccountException();// 没找到帐号
		}
		if (Boolean.TRUE.equals(user.getLocked())) {
			throw new LockedAccountException(); // 帐号锁定
		}

		// 返回认证信息由父类AuthenticationRealm进行认证
		SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, user.getPassword(),
				ByteSource.Util.bytes(user.getCredentialsSalt()), this.getName());
		return simpleAuthenticationInfo;
	}

	// 用于授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		// 获取身份信息
		String username = (String) principals.getPrimaryPrincipal();
		SysUser user = sysUserService.getUserByUsername(username);
		long userId = user.getId();
		// 根据用户id从数据库中查询权限数据

		// 将权限信息封装为AuthorizationInfo
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		// simpleAuthorizationInfo.setRoles(sysUserService.findRoles(username));
		Set<String> permissions = Collections.EMPTY_SET;

		List<String> permsList = new ArrayList<String>();

		// 系统管理员，拥有最高权限
		if (userId == Const.SUPER_ADMIN) {
			permissions = sysResourceService.findAllPermissions();
			permsList.addAll(permissions);
		} else {
			permsList = sysUserService.queryAllPerms(userId);
		}

		// 用户权限列表
		Set<String> permsSet = new HashSet<>();
		for (String perms : permsList) {
			if (StringUtils.isBlank(perms)) {
				continue;
			}
			if(perms.contains("*")){
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}

		simpleAuthorizationInfo.setStringPermissions(permsSet);
		return simpleAuthorizationInfo;
	}

}